/**
 * 
 */
package loansManagement;

import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.AttributeOverride;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.Column;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;

import exceptions.*;
import subscribersManagement.Subscriber;
import outils.StringCalendar;
import specimensManagement.Specimen;
import main.Constraints;
import mediasManagement.Media;

/**
 * @author F
 *
 */

@Entity
@AssociationOverride(name = "pk.subscriber",
joinColumns=@JoinColumn(name="id_subscriber"))
@AttributeOverride(name = "pk.specimen",
column=@Column(name="id_specimen"))
public class Loan implements java.io.Serializable  {

	// Fields
	/**
	 * @uml.property  name="loanId"
	 * @uml.associationEnd  inverse="loan:loansManagement.LoanId"
	 */
	@EmbeddedId
	private LoanId pk;

	/**
	 * @uml.property  name="media"
	 * @uml.associationEnd  inverse="loans:mediasManagement.Media"
	 */
	@Transient
	private Media media;
	
	/**
	 * @uml.property  name="dateReturn"
	 */
	
	private Calendar dateReturn;

	
	//Accessors
	
	/**
	 * Getter of the property <tt>subscriber</tt>
	 * @return  Returns the subscriber.
	 * @uml.property  name="subscriber"
	 */
	@Transient
	public Subscriber getLender() {
	
		return getPk().getSubscriber();
	}

	/**
	 * Setter of the property <tt>subscriber</tt>
	 * @param subscriber  The subscriber to set.
	 * @uml.property  name="subscriber"
	 */
	public void setLender(Subscriber lender) {
		getPk().setSubscriber(lender);
	}


	/**
	 * Getter of the property <tt>specimen</tt>
	 * @return  Returns the specimen.
	 * @uml.property  name="specimen"
	 */
	@Transient
	public Specimen getSpecimen() {
		return getPk().getSpecimen();
	}

	/**
	 * Setter of the property <tt>exemplary</tt>
	 * @param specimen  The exemplary to set.
	 * @uml.property  name="exemplary"
	 */
	public void setSpecimen(Specimen specimen) {
		getPk().setSpecimen(specimen);
	}

	public LoanId getPk() {
		return pk;
	}

	public void setPk(LoanId pk) {
		this.pk = pk;
	}

	public Media getMedia() {
		return media;
	}

	public void setMedia(Media media) {
		this.media = media;
	}

	public Calendar getDateReturn() {
		return dateReturn;
	}

	public void setDateReturn(Calendar dateReturn) {
		this.dateReturn = dateReturn;
	}
	
	
	//Constructors


	public Loan(Media media, Subscriber lender) throws BadParametersException, LentMediaException, ChildLoanException {
		// TODO Auto-generated constructor stub
		if ((media == null) || (lender == null))
			throw new BadParametersException();
		this.pk= new LoanId();
		this.media = media;
		setLender(lender);
		Calendar rDate = new GregorianCalendar();
		rDate.add(Calendar.MONTH, Constraints.loanDELAY);
		this.dateReturn = rDate;
		
		// Update the subscriber if he can lend
		setSpecimen(media.lend(this));
		//lender.lend(this);
		
		// Update the book if not already lent
		
		//setExemplary(media.lend(this));
		lender.lend(this);
	}
	
	public Loan (){
		this.pk=new LoanId();
	}

	//Methods
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Loan that = (Loan) o;

		if (getPk() != null ? !getPk().equals(that.getPk())
				: that.getPk() != null)
			return false;

		return true;
	}

	public int hashCode() {
		return (getPk() != null ? getPk().hashCode() : 0);
	}
}
